home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’95 / What's On My Mac / main.c < prev    next >
Text File  |  1995-06-24  |  12KB  |  478 lines

  1. /*****
  2.  *
  3.  *    What's On My Mac
  4.  *
  5.  *    By Scott T Boyd & Grant Neufeld
  6.  *
  7.  *    Copyright ©1995 by Grant Neufeld & Scott T Boyd
  8.  *    see full copyright notice in cgi.c
  9.  *
  10.  *    Based in part on "Responder" written by John O'Fallon
  11.  *
  12.  *****/
  13.  
  14. #define __MainSegment__
  15.  
  16. #include <AppleEvents.h>
  17. #include <Menus.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <Strings.h>
  22. #include <TextUtils.h>
  23.  
  24. #include "cgi.h"
  25. #include "DebugUtil.h"
  26. #include "GrabFrontWindow.h"
  27. #include "MemoryUtil.h"
  28.  
  29.  
  30. /***  CONSTANT DEFINITIONS  ***/
  31.  
  32. #define NIL                    0L
  33. #define APPLE_EVENT_CLASS    'WWWΩ'
  34. #define APPLE_EVENT_ID        'sdoc'
  35. #define MENU_DEF_APPLE        128
  36. #define MENU_DEF_FILE        129
  37. #define ITEM_DEF_QUIT        1
  38. #define BUFFER_SIZE            32768
  39. #define DELIM_STRING        "Ω"
  40. #define DELIM_CHAR            'Ω'
  41.  
  42. #define krHTMLStrs            128
  43. #define krHTMLStrTop        1
  44. #define krHTMLStrImg        2
  45. #define krHTMLStrBottom        3
  46.  
  47.  
  48. /***  LOCAL VARIABLES  ***/
  49.  
  50.     char    vImageFileName[32];
  51.     long    vImageFileNameSize;
  52.     
  53.     Str255    vHTMLStrTop;
  54.     long    vHTMLStrTopSize;
  55.     Str255    vHTMLStrImg;
  56.     long    vHTMLStrImgSize;
  57.     Str255    vHTMLStrBottom;
  58.     long    vHTMLStrBottomSize;
  59.  
  60.  
  61. /*** FUNCTION PROTOTYPES  ***/
  62.  
  63.         void    HandleKeyDown        ( int, int );
  64.         void    HandleMouseDown        ( Point );
  65.         void    HandleMenuChoice    ( long );
  66.         void    UpdateScreen        ( void );
  67.         void    AboutBox            ( void );
  68.         
  69. pascal    OSErr    HandOpenApp            ( AppleEvent *, AppleEvent *, long );
  70. pascal    OSErr    HandOpenDoc            ( AppleEvent *, AppleEvent *, long );
  71. pascal    OSErr    HandPrintDoc        ( AppleEvent *, AppleEvent *, long );
  72. pascal    OSErr    HandQuitApp            ( AppleEvent *, AppleEvent *, long );
  73. pascal    OSErr    HandClientRequest    ( AppleEvent *, AppleEvent *, long );
  74.     
  75.         void    StatusSetUp            ( void );
  76.         void    InstallAllEvents    ( void );
  77.         
  78.         void    MyCGIInit            ( void );
  79.         void    MyCGIProcess        ( CGIHdl );
  80.  
  81.  
  82. /***  GLOBAL VARIABLES  ***/
  83.  
  84. int                QuitApp;                    // Boolean for "Should we quit"?
  85. MenuHandle        MenuApple;                    // Handle to the Apple Menu (for finding DA names)
  86. WindowPtr        MyWindow;                    // Handle to our window
  87. WindowRecord    MyWindArea;                    // A window record for the status screen
  88. PicHandle        MyPic;                        // A handle to the window background PICT
  89.  
  90.  
  91. /* MAIN sets up the environment and executes the event loop. */
  92. void
  93. main ( void )
  94. {
  95.     OSErr            MyErr;
  96.     Handle            MenuBar;                                
  97.     MenuHandle        MenuFile;
  98.     EventRecord        Action;
  99.     
  100.     /* Initialize our 'quit' global */
  101.     QuitApp = FALSE;
  102.     
  103.     /* Now do all the right Mac things (See Inside Mac) */
  104.     InitGraf    ( &qd.thePort );
  105.     InitFonts    ();
  106.     InitWindows    ();
  107.     InitMenus    ();
  108.     FlushEvents    ( everyEvent, nil );
  109.     TEInit        ();
  110.     InitDialogs    ( NIL );
  111.     InitCursor    ();
  112.     
  113.     MaxApplZone ();
  114.     
  115.     /* Menu Bar set-up, see Inside Mac for details */
  116.     MenuBar            = GetNewMBar ( MENU_DEF_APPLE );
  117.     SetMenuBar        ( MenuBar );
  118.     MenuApple        = GetMenuHandle ( MENU_DEF_APPLE );
  119.     MenuFile        = GetMenu ( MENU_DEF_FILE );
  120.     AppendResMenu    ( MenuApple, 'DRVR' );    
  121.     DrawMenuBar        ();
  122.     
  123.     // Let the Event Manager know we want AppleEvents
  124.     InstallAllEvents ();
  125.     
  126.     InitCGIUtil ();
  127.     MyCGIInit    ();
  128.     
  129.     StatusSetUp ();
  130.     
  131.     /* Go through the event loop as long as we aren't supposed to quit */
  132.     while ( QuitApp == FALSE )
  133.     {
  134.         WaitNextEvent ( everyEvent, &Action, 0L, 0L );    // Ask the OS for an event
  135.         
  136.         switch (Action.what)
  137.         {
  138.             case mouseDown:                        // They clicked the mouse...
  139.                 HandleMouseDown ( Action.where );
  140.                 break;
  141.                 
  142.             case keyDown:                        // They pressed a key...
  143.                 HandleKeyDown ( (int)Action.message,(int)Action.modifiers );
  144.                 break;
  145.                 
  146.             case updateEvt:                        // Our window needs to be re-painted...
  147.                 if ( (WindowPtr)Action.message == MyWindow )
  148.                 {
  149.                     BeginUpdate        ( MyWindow );
  150.                     UpdateScreen    ();
  151.                     EndUpdate        ( MyWindow );
  152.                 }
  153.                 break;
  154.                 
  155.             case kHighLevelEvent:                // We have an AppleEvent... so let the OS...
  156.                 MyErr = AEProcessAppleEvent ( &Action );    // dispatch it (see Inside Mac).
  157.                 
  158.                 if ( MyErr != noErr )
  159.                 {
  160.                     SysBeep (2);                // Well behaved apps would do more than beep!
  161.                 }
  162.                 break;
  163.         }
  164.     }
  165. }
  166.  
  167.  
  168. /****************************************************************/
  169. /* When a key is pressed, this routine processes it.            */
  170. /****************************************************************/
  171. void
  172. HandleKeyDown (int KeyPress, int Modifiers)
  173. {
  174.     char Key;
  175.     int Modifier;
  176.     long int MenuChoice;
  177.     
  178.     Key = KeyPress & charCodeMask;
  179.     Modifier = Modifiers & cmdKey;
  180.     
  181.     if (Modifier > 0)
  182.     {                    // We pay attention only to Command keys.
  183.         MenuChoice = MenuKey (Key);        // If the user hit a shortcut key,
  184.         HandleMenuChoice (MenuChoice);    // see if there's a menu option to execute.
  185.     }
  186. }
  187.  
  188.  
  189. /****************************************************************/
  190. /* When the mouse button gets pressed, this routine handles it.    */
  191. /****************************************************************/
  192.  
  193. void HandleMouseDown (Point Where)
  194. {
  195.     WindowPtr WhichWind;
  196.     short int WhichPart;
  197.     long int MenuChoice;
  198.     Rect DragRect;            // Used to define dragable area for our window
  199.     
  200.     WhichPart = FindWindow (Where, &WhichWind);    // Find out where they clicked
  201.     
  202.     switch (WhichPart)
  203.     {
  204.         case inMenuBar:                            // clicking in the menu bar is interesting...
  205.             MenuChoice = MenuSelect (Where);    // tell the OS to handle it
  206.             HandleMenuChoice (MenuChoice);        // and process any option they may have chosen
  207.             break;
  208.             
  209.         case inDrag:
  210.             DragRect.top = -32767;                // set-up the drag area
  211.             DragRect.bottom = 32767;
  212.             DragRect.left = -32767;
  213.             DragRect.right = 32767;
  214.             DragWindow ( WhichWind, Where, &DragRect );        // let the OS do the dragging
  215.             break;
  216.     }
  217. }
  218.  
  219.  
  220. /****************************************************************/
  221. /* When the user selects a menu option, either by mouse or         */
  222. /* shortcut key, this routine handles it.                         */
  223. /****************************************************************/
  224.  
  225. void HandleMenuChoice (long MenuChoice)
  226. {
  227.     int TheMenu;
  228.     int TheItem;
  229.     Str255 DAName;
  230.     int DANumber;
  231.     
  232.     if (MenuChoice != 0)
  233.     {                    // Ignore NULL selections
  234.         TheMenu = HiWord (MenuChoice);        // find the menu number
  235.         TheItem = LoWord (MenuChoice);        // find the item number
  236.         
  237.         switch (TheMenu)
  238.         {
  239.             case MENU_DEF_APPLE:            
  240.                 if (TheItem == 1)
  241.                 {
  242.                     AboutBox ();
  243.                 }
  244.                 else
  245.                 {
  246.                     GetMenuItemText (MenuApple,TheItem,DAName);
  247.                     DANumber = OpenDeskAcc (DAName);
  248.                 }
  249.                 break;
  250.             case MENU_DEF_FILE:
  251.                 switch (TheItem)
  252.                 {
  253.                     case ITEM_DEF_QUIT:
  254.                         QuitApp=TRUE;
  255.                         break;
  256.                 }
  257.                 break;
  258.         }
  259.         HiliteMenu (0);
  260.     }
  261. } /*  */
  262.  
  263.  
  264. /****************************************************************/
  265. /* STATUSSETUP creates our status window and paints the            */
  266. /* background.                                                    */
  267. /****************************************************************/
  268.  
  269. void StatusSetUp ()
  270. {
  271.     Rect WindowRect;
  272.     Rect PicRect;
  273.     
  274.     WindowRect.top        =40;
  275.     WindowRect.bottom    =467;
  276.     WindowRect.left        =20;
  277.     WindowRect.right    =735;
  278.     
  279.     MyWindow = NewWindow ( &MyWindArea, &WindowRect, "\pWhat's On My Mac", TRUE, (int)0,
  280.         (WindowPtr)(-1), FALSE, (long)5 );
  281.     
  282.     // Open and Show a status window
  283.     ShowWindow    (MyWindow);
  284.     SetPort        (MyWindow);
  285.     
  286.     MyPic = GetPicture (128);    // Load the background of the window from a PICT resource
  287.     if ( MyPic != 0 )
  288.     {
  289.         // Make sure we got it
  290.         PicRect = (*MyPic)->picFrame;    // size the rect
  291.         DrawPicture (MyPic, &PicRect);    // and display it
  292.     }
  293. }
  294.  
  295.  
  296. /****************************************************************/
  297. /* UPDATESCREEN updates each field on the status screen.        */
  298. /****************************************************************/
  299. void
  300. UpdateScreen ()
  301. {
  302.     Rect PicRect;
  303.     
  304.     if ( MyPic != nil )
  305.     {
  306.         // As long as we still have a hold of the PICT
  307.         PicRect = (*MyPic)->picFrame;    // get it's rect
  308.         DrawPicture ( MyPic, &PicRect );    // and display it
  309.     }
  310. }
  311.  
  312.  
  313. /******************************************************/
  314. /* ABOUTBOX - Displays a window with the about        */
  315. /*        box as a PICT resource, this proc             */
  316. /*        automatically displays a centered window with */
  317. /*        the PICT in it and waits for the user to       */
  318. /*        click the mouse button.                          */
  319. /******************************************************/
  320. void
  321. AboutBox ( void )
  322. {
  323.     SysBeep ( 2 );
  324. }
  325.  
  326.  
  327. /*  */
  328. void
  329. MyCGIInit ( void )
  330. {
  331.     Handle    theResource;
  332.     
  333.     /* init html strings */
  334.     
  335.     GetIndString ( vHTMLStrTop, krHTMLStrs, krHTMLStrTop );
  336.     P2CStr ( vHTMLStrTop );
  337.     vHTMLStrTopSize = strlen ( (char *)vHTMLStrTop );
  338.      
  339.     GetIndString ( vHTMLStrImg, krHTMLStrs, krHTMLStrImg );
  340.     P2CStr ( vHTMLStrImg );
  341.     vHTMLStrImgSize = strlen ( (char *)vHTMLStrImg );
  342.     
  343.     GetIndString ( vHTMLStrBottom, krHTMLStrs, krHTMLStrBottom );
  344.     P2CStr ( vHTMLStrBottom );
  345.     vHTMLStrBottomSize = strlen ( (char *)vHTMLStrBottom );
  346.     
  347.     /* init file name string */
  348.     theResource = Get1Resource ( 'CSTR', 128 );
  349.     
  350.     my_assert ( strlen((char*)(*theResource)) < 32, "MyCGIInit: theResource is too big" );
  351.     
  352.     HLock    ( theResource );
  353.     strcpy    ( vImageFileName, (char*)(*theResource) );
  354.     HUnlock    ( theResource );
  355.     
  356.     ReleaseResource ( theResource );
  357.     
  358.     vImageFileNameSize = strlen ( vImageFileName );
  359. } /* MyCGIInit */
  360.  
  361.  
  362. /*  */
  363. void
  364. MyCGIProcess ( CGIHdl theCGIHandle )
  365. {
  366.     long    totalSize;
  367.     unsigned short    imgwidth;
  368.     unsigned short    imgheight;
  369.     unsigned short    clickH;
  370.     unsigned short    clickV;
  371.     char *    offset;
  372.     
  373.     totalSize = gHTTPHeaderOKSize + vImageFileNameSize + vHTMLStrTopSize
  374.         + vHTMLStrImgSize + 26 + vHTMLStrBottomSize;
  375.     
  376.     HLock ( (Handle)theCGIHandle );
  377.     (*theCGIHandle)->responseData = (char *) MyNewPtr ( totalSize, nil );
  378.     
  379.     if ( (*theCGIHandle)->responseData != nil )
  380.     {
  381.         offset        = strchr ( (*theCGIHandle)->responseData, ',' );
  382.         offset[0]    = nil;
  383.         
  384.         clickH = atoi ( (*theCGIHandle)->http_search_args );
  385.         clickV = atoi ( offset + 1 );
  386.         
  387.         HUnlock ( (Handle)theCGIHandle );
  388.         
  389.         ClickOnTheFrontWindow ( clickH, clickV );
  390.     }
  391.     
  392.     GrabFrontWindowAsJPEG ( &imgwidth, &imgheight );
  393.     
  394.     if ( (*theCGIHandle)->responseData != nil )
  395.     {
  396.         (*theCGIHandle)->responseSize    = totalSize;
  397.         
  398.         /* generate an HTML string and send it back */
  399.         sprintf ( (*theCGIHandle)->responseData,
  400.             "%s%s%s%s WIDTH=%d HEIGHT=%d%s",
  401.             gHTTPHeaderOK, vHTMLStrTop, vImageFileName, vHTMLStrImg,
  402.             imgwidth, imgheight, vHTMLStrBottom );
  403.         
  404.         SnapshotSound ();
  405.     }
  406. } /* MyCGIProcess */
  407.  
  408.  
  409. /* registers the event handlers with the Event Manager. */
  410. #pragma segment AppleEvent
  411. void
  412. InstallAllEvents ( void )
  413. {
  414.     OSErr                theErr;
  415.     AEEventHandlerUPP    MyUPP;
  416.     
  417.     /* get the Universal Proc Pointer (required for PPC calls) */
  418.     MyUPP = NewAEEventHandlerProc(HandOpenApp);
  419.     /* install the handler */
  420.     theErr = AEInstallEventHandler (kCoreEventClass,kAEOpenApplication,MyUPP,0,FALSE);
  421.     
  422.     MyUPP = NewAEEventHandlerProc(HandOpenDoc);
  423.     theErr = AEInstallEventHandler (kCoreEventClass,kAEOpenDocuments,MyUPP,0,FALSE);
  424.     
  425.     MyUPP = NewAEEventHandlerProc(HandPrintDoc);
  426.     theErr = AEInstallEventHandler (kCoreEventClass,kAEPrintDocuments,MyUPP,0,FALSE);
  427.     
  428.     MyUPP = NewAEEventHandlerProc(HandQuitApp);
  429.     theErr = AEInstallEventHandler (kCoreEventClass,kAEQuitApplication,MyUPP,0,FALSE);
  430.     
  431.     MyUPP = NewAEEventHandlerProc ( CGIAEHandle );
  432.     theErr = AEInstallEventHandler (APPLE_EVENT_CLASS,APPLE_EVENT_ID,MyUPP,0,FALSE);
  433.     
  434.     if ( theErr != noErr )
  435.     {
  436.         // Well behaved apps would do more than beep!
  437.         SysBeep (2);
  438.     }
  439. } /* InstallAllEvents */
  440.  
  441.  
  442. /**************************************************************/
  443. /* APPLE EVENT ROUTINES: Handlers, Installers, and Processors */
  444. /**************************************************************/
  445.  
  446. #pragma segment AppleEvent
  447. pascal OSErr HandOpenApp (AppleEvent *TheRequest, AppleEvent *TheReply, long Reference)
  448. {
  449.     UpdateScreen ();
  450.     
  451.     return (noErr);
  452. }
  453.  
  454. #pragma segment AppleEvent
  455. pascal OSErr HandOpenDoc (AppleEvent *TheRequest, AppleEvent *TheReply, long Reference)
  456. {
  457.     UpdateScreen ();
  458.     
  459.     return (noErr);
  460. }
  461.  
  462. #pragma segment AppleEvent
  463. pascal OSErr HandPrintDoc (AppleEvent *TheRequest, AppleEvent *TheReply, long Reference)
  464. {
  465.     UpdateScreen ();
  466.     
  467.     return (noErr);
  468. }
  469.  
  470. #pragma segment AppleEvent
  471. pascal OSErr HandQuitApp (AppleEvent *TheRequest, AppleEvent *TheReply, long Reference)
  472. {
  473.     UpdateScreen ();
  474.     QuitApp = TRUE;
  475.     
  476.     return (noErr);
  477. }
  478. #pragma segment Main